package app.util
{
	import app.gui.control.*;
	import app.gui.control.slide.*;
	import app.util.image.*;
	import app.util.image.action.*;
	
	import flash.display.*;
	import flash.geom.*;
	
	import mx.collections.*;
	import mx.controls.*;
	import mx.core.*;
	import mx.events.*;
	import mx.managers.*;
	
	public class Mediator
	{		
		private static var main:MainCanvas;
		private static var hasImage:Boolean;
		private static var cfg:Config;
		private static var io:ImageIO;
		private static var cutter:ImageCutter;
		private static var repair:ImageRepair;
		private static var log:Logger;
		
		public static function initialize():void
		{
			io = new ImageIO();
			cfg = new Config();
			cutter = new ImageCutter();
			repair = new ImageRepair();
			log = new Logger();
			cfg.buildFromFile();			
		}
		
		public static function registerApplication(m:MainCanvas):void
		{
			main = m;
			switchToNoImageMode(true);
			applyConfig();
			
			alert("Aqua-Eye 1.0 application initilization done");
		} 
		
		public static function applyConfig():void
		{
			(main.parentApplication as WindowedApplication).alwaysInFront = cfg.alwaysFront;
			log.setEnable(cfg.enableLog);
		}
		
		public static function getApplication():AquaEyeProject
		{
			return main.parentApplication as AquaEyeProject;
		}
		
		public static function getMain():MainCanvas
		{
			return main;
		}
		
		public static function getLogger():Logger
		{
			return log;
		}
		
		public static function getConfig():Config
		{
			return cfg;
		}
		
		public static function getImageCutter():ImageCutter
		{
			return cutter;
		}
		
		public static function getImageRepair():ImageRepair
		{
			return repair;
		}		
		
		public static function switchOperationPanel(index:int):void
		{
			//Do uninstall
			cutter.uninstall();
			repair.uninstall();			
			(main.operationPanel.selectedChild as Object).stack.selectedIndex = 0;
			
			//Do install
			main.operationPanel.selectedIndex = index;
			
			var len:int = main.operationPanel.getChildren().length;
			var child:Container = main.operationPanel.selectedChild;
			switch(index)
			{
				case 0:
					var fs:FileSlide = child as FileSlide;
					fs.stack.selectedIndex = 0;
					fs.exportButton.enabled = hasImage;
					fs.saveButton.enabled = hasImage;				
					break;
				case len - 1:
				case len - 2:
					break;
				default:
					child.enabled = hasImage;				
					break;
			}
		}
		
		public static function alert(text:String):void
		{
			trace("[ALERT]\t" + text);
			log.log(text);
			getApplication().status = "  " + text;
		} 
		
		public static function switchToNoImageMode(value:Boolean):void
		{
			hasImage = !value;
			main.redoButton.enabled = hasImage;
			main.undoButton.enabled = hasImage;
			main.displayer.stateBox.visible = hasImage;
			main.displayer.stack.selectedIndex = (value ? 0 : 1);
			if(value) 
			{
				main.actionList.dataProvider = null;
			}
			switchOperationPanel(main.operationPanel.selectedIndex);		
		}
		
		public static function getImageIO():ImageIO
		{
			return io;
		}		
		
		public static function getAllImages():Array
		{
			return main.displayer.getAllImages();
		}
		
		public static function getCurrentBitmapData():BitmapData
		{
			var cfg:ImageConfig = getCurrentImageConfig();
			return cfg.images[cfg.stateIndex - 1];
		}
		
		public static function getCurrentImageConfig():ImageConfig
		{
			return getCurrentAquaImage().getImageConfig();
		}
		
		public static function getCurrentAquaImage():AquaImage
		{
			return (main.displayer.imageNavigator.selectedChild as AquaImage);
		} 
		
		public static function getCurrentImage():Image
		{
			return getCurrentAquaImage().getImage();
		} 		
		
		public static function previewAction(action:AbstractAction):void
		{
			try
			{
				getCurrentAquaImage().loadImage(action.getActionedBitmapData());
			}
			catch(e:Error)
			{
				handleImageProcessingError(e);
			}
		}	
		
		public static function handleImageProcessingError(e:Error):void
		{
			trace(e.getStackTrace());
			if(e is ArgumentError)
			{
				Mediator.alert("Error at applying effect : The application may be running at restrict mode");	
			}
			else
			{
				Mediator.alert("Error at applying effect : " + e.message);
			}
		}
			
	}
}